package org.xtext.runtime.formula;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.xtext.runtime.term.ITerm;
import org.xtext.runtime.term.Variable;
import org.xtext.runtime.util.Bindings;
import org.xtext.runtime.util.ILogicVisitor;

public class AcreHistory implements IFormula {
	ITerm cid;
	ITerm index;
	ITerm type;
	String performative;
	Predicate content;
	
	public AcreHistory(ITerm cid, ITerm index, ITerm type, String performative, Predicate content) {
		this.cid = cid;
		this.index = index;
		this.type = type;
		this.performative = performative;
		this.content = content;
	}

	@Override
	public IFormula copy() {
		return new AcreHistory(cid.copy(), index.copy(), type.copy(), performative, content.copy());
	}

	@Override
	public Set<Variable> variables() {
		Set<Variable> variables = new HashSet<Variable>();
		if (cid instanceof Variable) variables.add((Variable) cid);
		if (index instanceof Variable) variables.add((Variable) index);
		if (type instanceof Variable) variables.add((Variable) type);
		variables.addAll(content.variables());
		return variables;
	}

	@Override
	public AcreHistory apply(Bindings bindings) {
//		System.out.println("about to apply: " + bindings + " to: " + this);
		return new AcreHistory(
				cid.apply(bindings),
				index.apply(bindings),
				type.apply(bindings),
				performative,
				content.apply(bindings)
		);
	}

	@Override
	public IFormula copy(Map<String, Variable> vars) {
		return new AcreHistory(
				cid.copy(vars),
				index.copy(vars),
				type.copy(vars),
				performative,
				content.copy(vars)
		);
	}

	@Override
	public boolean hasFreeVariables() {
		if (cid.hasFreeVariables()) return true;
		if (index.hasFreeVariables()) return true;
		if (type.hasFreeVariables()) return true;
		return content.hasFreeVariables();
	}

	@Override
	public Object accept(ILogicVisitor visitor) {
		return visitor.visit(this);
	}

	public Predicate getContent() {
		return content;
	}

	public ITerm getConversationId() {
		return cid;
	}
	
	public ITerm getIndex() {
		return index;
	}
	
	public ITerm getType() {
		return type;
	}
	
	public String getPerformative() {
		return performative;
	}
}
